import { h, Schema } from "koishi"
import { createVerify } from "crypto"

export const name = "-lnnbot-patron-afdian-webhook"
export const inject = [
  "server",
  "database", // assignee
]

export const Config = Schema.object({
  webhookPath: Schema.string().default("/patron/afdian"),
  channel: String, // platform:channelId
  pingUserId: Schema.string(),
})

const webhookPublicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwwdaCg1Bt+UKZKs0R54y
lYnuANma49IpgoOwNmk3a0rhg/PQuhUJ0EOZSowIC44l0K3+fqGns3Ygi4AfmEfS
4EKbdk1ahSxu7Zkp2rHMt+R9GarQFQkwSS/5x1dYiHNVMiR8oIXDgjmvxuNes2Cr
8fw9dEF0xNBKdkKgG2qAawcN1nZrdyaKWtPVT9m2Hl0ddOO9thZmVLFOb9NVzgYf
jEgI+KWX6aY19Ka/ghv/L4t1IXmz9pctablN5S0CRWpJW3Cn0k6zSXgjVdKm4uN7
jRlgSRaf/Ind46vMCm3N2sgwxu/g3bnooW+db0iLo13zzuvyn727Q3UDQ0MmZcEW
MQIDAQAB
-----END PUBLIC KEY-----`

export function apply(ctx, config) {
  function verifySignature(signStr, sign, publicKey) {
    try {
      const verifier = createVerify("SHA256").update(signStr, "utf8")
      const signatureBuffer = Buffer.from(sign, "base64")
      return verifier.verify(publicKey, signatureBuffer)
    } catch (error) {
      ctx.logger.error("Verification error:", error);
      return false
    }
  }

  async function send(content) {
    ctx.logger.debug(content)
    await ctx.broadcast([config.channel], content)
  }

  ctx.server.post(config.webhookPath, r => {
    const payload = r.request.body
    ctx.logger.info(r.request, payload)

    const signStr =
      payload?.data?.order?.out_trade_no +
      payload?.data?.order?.user_id +
      payload?.data?.order?.plan_id +
      payload?.data?.order?.total_amount
    if (!verifySignature(signStr, payload?.data?.sign, webhookPublicKey)) {
      r.status = 403
      r.body = '{"ec":-403003,"em":"invalid sign"}'
      ctx.logger.warn("sign verification failed")
      return
    }

    r.status = 200
    r.body = '{"ec":200,"em":"ok"}'

    send([
      config.pingUserId && [h.at(config.pingUserId), h.text(" ")],
      h("i18n:object", { path: "patron.afdian.received", data: { ...payload.data.order } }),
    ].flat().filter(Boolean))
  })

  ctx.i18n.define("zh-CN", "patron.afdian", {
    received: "收到一笔{#if user_name}来自“{user_name}”的{/if}爱发电赞助：{(show_amount / month).toFixed(2)} 元 * {month} 月，共 {show_amount} 元{#if remark}，备注：{remark}{/if}",
  })
}
